﻿using System;
namespace RunCodeInAppDomain
{
    public class DomainRunner
    {
        public static object RunInAppDomain(System.Delegate delg, AppDomain targetDomain, params object[] args)
        {
            domainDomainRunner runner = new domainDomainRunner(delg, args, delg.GetHashCode());
            targetDomain.DoCallBack(new CrossAppDomainDelegate(runner.Invoke));
            return targetDomain.GetData("appDomainResult" + delg.GetHashCode());
            //return targetDomain.GetData("appDomainResult");
            //return null;
        }
        public static object RunInAppDomain(System.Delegate delg, params object[] args)
        {
            AppDomain tempDomain = AppDomain.CreateDomain("domain_RunInAppDomain" + delg.GetHashCode());
            object returnValue = null;
            try
            {
                returnValue = RunInAppDomain(delg, tempDomain, args);
            }
            finally
            {
                AppDomain.Unload(tempDomain);
            }
            return returnValue;
        }

        [Serializable]
        internal class domainDomainRunner
        {
            private System.Delegate _delegate;
            private object[] _arguments;
            public int _hash = 0;
            public domainDomainRunner(System.Delegate delg, object[] args, int hash)
            {
                _delegate = delg;
                _arguments = args;
                _hash = hash;
            }
            public void Invoke()
            {
                Console.WriteLine("I'm running in domain named {0}", AppDomain.CurrentDomain.FriendlyName);
                if (_delegate != null)
                    AppDomain.CurrentDomain.SetData("appDomainResult" + _hash, _delegate.DynamicInvoke(_arguments));
        
                  //  AppDomain.CurrentDomain.SetData("appDomainResult", _delegate.DynamicInvoke(_arguments));
           }
        }
    }
}
